// 流模块中文封装
const stream = require('stream');
const fs = require('fs');

/**
 * 创建可读流
 * @param {string} 路径 - 文件路径
 * @param {Object} 选项 - 可读流选项
 * @returns {fs.ReadStream} 可读流实例
 */
function 创建可读流(路径, 选项) {
  return fs.createReadStream(路径, 选项);
}

/**
 * 创建可写流
 * @param {string} 路径 - 文件路径
 * @param {Object} 选项 - 可写流选项
 * @returns {fs.WriteStream} 可写流实例
 */
function 创建可写流(路径, 选项) {
  return fs.createWriteStream(路径, 选项);
}

/**
 * 创建转换流
 * @param {Object} 选项 - 转换流选项
 * @returns {stream.Transform} 转换流实例
 */
function 创建转换流(选项) {
  return new stream.Transform(选项);
}

/**
 * 创建直通流
 * @param {Object} 选项 - 直通流选项
 * @returns {stream.PassThrough} 直通流实例
 */
function 创建直通流(选项) {
  return new stream.PassThrough(选项);
}

/**
 * 管道流连接
 * @param {stream.Readable} 可读流 - 源可读流
 * @param {stream.Writable} 可写流 - 目标可写流
 * @returns {stream.Writable} 目标可写流，用于链式调用
 */
function 管道连接(可读流, 可写流) {
  return 可读流.pipe(可写流);
}

/**
 * 解除管道连接
 * @param {stream.Readable} 可读流 - 源可读流
 * @param {stream.Writable} 可写流 - 目标可写流
 * @returns {stream.Readable} 源可读流
 */
function 解除管道连接(可读流, 可写流) {
  return 可读流.unpipe(可写流);
}

/**
 * 设置流事件监听
 * @param {stream.Stream} 流对象 - 流实例
 * @param {string} 事件名 - 事件名称（如'data', 'end', 'error'等）
 * @param {Function} 回调函数 - 事件回调
 */
function 监听流事件(流对象, 事件名, 回调函数) {
  流对象.on(事件名, 回调函数);
}

/**
 * 暂停可读流
 * @param {stream.Readable} 可读流 - 可读流实例
 * @returns {stream.Readable} 可读流实例
 */
function 暂停流(可读流) {
  return 可读流.pause();
}

/**
 * 恢复可读流
 * @param {stream.Readable} 可读流 - 可读流实例
 * @returns {stream.Readable} 可读流实例
 */
function 恢复流(可读流) {
  return 可读流.resume();
}

/**
 * 检查流是否可读
 * @param {stream.Stream} 流对象 - 流实例
 * @returns {boolean} 是否可读
 */
function 是可读流(流对象) {
  return 流对象.readable;
}

/**
 * 检查流是否可写
 * @param {stream.Stream} 流对象 - 流实例
 * @returns {boolean} 是否可写
 */
function 是可写流(流对象) {
  return 流对象.writable;
}

/**
 * 从可读流读取数据
 * @param {stream.Readable} 可读流 - 可读流实例
 * @param {number} 大小 - 要读取的字节数
 * @returns {Buffer|null} 读取的数据
 */
function 读取流数据(可读流, 大小) {
  return 可读流.read(大小);
}

/**
 * 向可写流写入数据
 * @param {stream.Writable} 可写流 - 可写流实例
 * @param {Buffer|string} 数据 - 要写入的数据
 * @param {string} 编码 - 数据编码
 * @param {Function} 回调函数 - 写入完成的回调
 * @returns {boolean} 是否需要等待'drain'事件
 */
function 写入流数据(可写流, 数据, 编码, 回调函数) {
  return 可写流.write(数据, 编码, 回调函数);
}

/**
 * 结束可写流
 * @param {stream.Writable} 可写流 - 可写流实例
 * @param {Buffer|string} 数据 - 最后的数据
 * @param {string} 编码 - 数据编码
 * @param {Function} 回调函数 - 结束的回调
 */
function 结束可写流(可写流, 数据, 编码, 回调函数) {
  可写流.end(数据, 编码, 回调函数);
}

/**
 * 复制文件（使用流）
 * @param {string} 源路径 - 源文件路径
 * @param {string} 目标路径 - 目标文件路径
 * @param {Function} 回调函数 - 复制完成的回调 (错误) => {}
 */
function 流式复制文件(源路径, 目标路径, 回调函数) {
  const 可读流 = 创建可读流(源路径);
  const 可写流 = 创建可写流(目标路径);
  
  可读流.on('error', (错误) => {
    关闭流(可读流);
    关闭流(可写流);
    if (回调函数) 回调函数(错误);
  });
  
  可写流.on('error', (错误) => {
    关闭流(可读流);
    关闭流(可写流);
    if (回调函数) 回调函数(错误);
  });
  
  可写流.on('finish', () => {
    if (回调函数) 回调函数(null);
  });
  
  管道连接(可读流, 可写流);
}

/**
 * 关闭流
 * @param {stream.Stream} 流对象 - 流实例
 * @param {Function} 回调函数 - 关闭完成的回调
 */
function 关闭流(流对象, 回调函数) {
  if (流对象.destroy) {
    流对象.destroy();
    if (回调函数) 回调函数();
  } else if (回调函数) {
    回调函数();
  }
}

/**
 * 创建双向流
 * @param {Object} 选项 - 双向流选项
 * @returns {stream.Duplex} 双向流实例
 */
function 创建双向流(选项) {
  return new stream.Duplex(选项);
}

module.exports = {
  创建可读流,
  创建可写流,
  创建转换流,
  创建直通流,
  创建双向流,
  管道连接,
  解除管道连接,
  监听流事件,
  暂停流,
  恢复流,
  是可读流,
  是可写流,
  读取流数据,
  写入流数据,
  结束可写流,
  流式复制文件,
  关闭流
};